﻿using System;

namespace Main
{
    /// <summary>
    /// Class for scheduling update/suspend/wakeup intervals.
    /// </summary>
    public class Schedule : ISchedule
    {
        #region Constructors

        public Schedule(TimeSpan checkInterval)
        {
            CheckInterval = checkInterval;
            NeedToSuspend = false;
            CheckAtStart = true;
        }

        public Schedule(TimeSpan checkInterval, bool needToSuspend, TimeSpan defaultTimeToSuspend)
            : this(checkInterval)
        {
            NeedToSuspend = needToSuspend;
            TimeToSuspendDefault = defaultTimeToSuspend;
            TimeToSuspendSucces = new TimeSpan(TimeToSuspendDefault.Ticks * 2);
        }

        #endregion

        #region Public members

        /// <summary>
        /// Property changed events.
        /// </summary>
        public event Action SuspendChanged;
        public event Action CheckIntervalChanged;

        /// <summary>
        /// Time in which computer must be suspended if no commands was received.
        /// </summary>
        public TimeSpan TimeToSuspendDefault
        {
            get { return _timeToSuspendDefault; }
            set
            {
                _timeToSuspendDefault = value;
                _OnSuspendChanged();
            }
        }

        /// <summary>
        /// Time in which computer must be suspended if commands was received.
        /// </summary>
        public TimeSpan TimeToSuspendSucces
        {
            get { return _timeToSuspendSucces; }
            set
            {
                _timeToSuspendSucces = value;
                _OnSuspendChanged();
            }
        }

        /// <summary>
        /// Interval in which mailbox must be checked.
        /// </summary>
        public TimeSpan CheckInterval
        {
            get { return _checkInterval; }
            set
            {
                _checkInterval = value;

                if (CheckIntervalChanged != null)
                    CheckIntervalChanged();
            }
        }

        /// <summary>
        /// Flag, showing should commands be checked on application start.
        /// </summary>
        public bool CheckAtStart { get; set; }

        /// <summary>
        /// Get time on which computer must be waked up.
        /// </summary>
        /// <param name="suspendTme">Time on which computer will be suspended.</param>
        public DateTime GetWakeupTime(DateTime suspendTme)
        {
            var time1 = 11;
            var time2 = 15;
            var time3 = 21;

            if (suspendTme > DateTime.Now.Date.AddHours(time3))
                return DateTime.Now.Date.AddDays(1).AddHours(time1);
            else if (suspendTme > DateTime.Now.Date.AddHours(time2))
                return DateTime.Now.Date.AddHours(time3);
            else if (suspendTme > DateTime.Now.Date.AddHours(time1))
                return DateTime.Now.Date.AddHours(time2);
            else
                return DateTime.Now.Date.AddHours(time1);
        }

        /// <summary>
        /// Flag, which show that computer must be suspended.
        /// </summary>
        public bool NeedToSuspend { get; set; }

        #endregion

        #region Private members

        private TimeSpan _checkInterval;
        private TimeSpan _timeToSuspendDefault;
        private TimeSpan _timeToSuspendSucces;

        private void _OnSuspendChanged()
        {
            if (SuspendChanged != null)
                SuspendChanged();
        }

        #endregion
    }
}
